"use strict"
import shUtils from "./util"
import { fabric } from "@/js/fabric";
export default function interactive() {
  this.initialize.apply(this, arguments);
}
interactive.prototype = {
  initialize() {
    this.root = Array.prototype.shift.call(arguments);
    this._initOptions();
    this._initStyle();
    this.initevents();
    this.dispatcher(Array.prototype.shift.call(arguments));
    this._drawtypeinit();
  },
  /**
   * 
   * @param {Object} options
   * 设置属性分发
   */
  dispatcher(options) {
    if (options.hasOwnProperty("style")) {
      this._setStyle(options.style)
    }
    if (options.hasOwnProperty("options")) {
      this._setoptions(options.options)
    }
  },
  /**
   * 设置样式
   * @param {style} style
   * 设置自定义绘制样式
   */
  _setStyle(style) {
    for (let key in this._style) {
      if (style[key]) {
        this._style[key] = style[key]
      }
    }
  },
  /**
   * 
   * @param {Obects} options 
   * 设置初始化状态
   */
  _setoptions(options) {
    for (let key in this._drawOptions) {
      if (options[key]) {
        this._drawOptions[key] = options[key]
      }
    }
  },
  /**
   * 设置默认初始化状态
   */
  _initOptions() {
    this._drawOptions = {
      _start: null,
      drawing: false,
      drawtype: null,
      isDrawingMode: false,
      _drawingobj: null
    }
  },
  /**
   * 初始化样式
   */
  _initStyle() {
    this._style = {
      fill: "red",
      stroke: "blue",
      strokeWidth: .5
    }
  },
  /**
   * 初始化事件
   */
  initevents() {
    let that = this;
    this.root.on("mouse:down", function (e) {
      //按住alt键才可拖动画布
      that._dragevents.mousedown(e, that);
      that._drawevent.mousedown(e, that);
    });
    //鼠标抬起
    this.root.on("mouse:up", function (e) {
      that._dragevents.mouseup(e, that)
      that._drawevent.mouseup(e, that);
    });
    this.root.on("mouse:move", function (e) {
      //绘制当前位置
      
      that._dragevents.mousemove(e, that);
      that._drawevent.mousemove(e, that);
    });
    this.root.on("mouse:dblclick", function (e) {
      //绘制当前位置
      that._drawevent.dblclick && that._drawevent.dblclick(e, that);
      that._dragevents.dblclick && that._dragevents.dblclick(e, that)
    });
  },
  /**
   * 绘制动作
   */
  _drawevent: {
    mousedown(e, that) {
      if (e && that._drawOptions.isDrawingMode && that._drawOptions.drawtype) {
        this.target = e.target;
        that.root.selection = false;
        that.root.drawing = true;
        shUtils.setState.call(that._drawOptions, {
          _start: e.absolutePointer,
          drawing: true
        })
        that.root.fire("drawstart", { massage: "drawstart" })
        if (this.target) {
          that.root.discardActiveObject(this.target);
          this.target.evented = false;
        }
        that._draw();
      }
    },
    mousemove(e, that) {
      if (that.root.drawing && that._drawOptions.drawtype) {
        if (that._drawOptions._drawingobj) {
          that._drawOptions._drawingobj.draw(that._drawOptions._start, e);
        }
      }
    },
    mouseup(e, that) {
      if (that.root.drawing) {
        if (that._drawOptions._drawingobj) {
          // that._drawOptions._drawingobj.draw(that._drawOptions._start, e.absolutePointer);

          if (typeof that._drawOptions._drawingobj.drawend == 'function') {
            that._drawOptions._drawingobj.drawend(that._drawOptions._start, e);
          };
        }
        //   console.log(target)
        // that.canvas.deactivateAll();
      }
    },
    dblclick(e, that) {
      if (that._drawOptions._drawingobj) {
        // that._drawOptions._drawingobj.draw(that._drawOptions._start, e.absolutePointer);

        if (typeof that._drawOptions._drawingobj.dblclick == 'function') {
          that._drawOptions._drawingobj.dblclick(that._drawOptions._start, e);
        };
      }
    }
  },
  /**
   * 拖拽动作
   * dragState 画布是否能被拖拽
   */
  _dragevents: {
    mousedown(e, that) {
      if (e.e.altKey && that.root.dragState) {
        this.frozen = {
          drawing: that.root.drawing
        }
        that.root.drawing = false;
        that.root.draging = true
        this.panning = true;
        that.root.selection = false;
        that.root.fire("dragstart", e);
      }
    },
    mousemove(e, that) {
      if (e && e.e.altKey && this.panning) {
        var delta = new fabric.Point(e.e.movementX, e.e.movementY);
        that.root.relativePan(delta);
        that.root.fire("ruler", {});
        that.root.fire("draging", e);
      }
      if (!that.root.draging && this.frozen) {
        that.root.drawing = this.frozen.drawing;
        this.frozen = null;
      }
    },
    mouseup(e, that) {
      this.panning = false;
      that.root.selection = true;
      that.root.draging = false
      this.frozen = null;
      that.root.fire("dragend", e);
    }
    // console.log("cc")
  },
  /**
   * 绘制分发
   * point,rect,line,circle
   */
  _draw() {
    return this._drawtypelist[this._drawOptions.drawtype].call(this, arguments)
  },
  _drawtypelist: {

  },
  _drawtypeinit: function () {
    this.addnewdrawtype("point", drawponit)
    this.addnewdrawtype("rect", drawrect)
    this.addnewdrawtype("line", drawline)
    this.addnewdrawtype("circle", drawcircle)
    this.addnewdrawtype("path", drwapath)
    this.addnewdrawtype("polygon", drawpolygon)
    this.addnewdrawtype("polyline", drawpolyline)
  },
  /**
   * 
   */
  addnewdrawtype(type, fn) {
    this._drawtypelist[type] = fn;
  },

  /**
   * 
   * @param {string} key 
   * @param {object} value 
   * 设置绘制状态
   */
  setOptions(key, value) {
    this._drawOptions[key] = value
  },
  /**
   * 获取绘制状态
   * @param {string} key
   *  @returns {object} 绘制状态
   */
  getOptions(key) {
    return this._drawOptions[key]
  },
  /**
   * @returns {object} 绑定的fabric实例
   */
  getRoot() {
    return this.root
  },
  /**
   * 设置画笔样式
   * @param {string} key 
   * @param {object} value 
   */
  setStyle(key, value) {
    this._style[key] = value
  },
  /**
   * 返回对应的画笔样式
   * @param {string} key 
   */
  getStyle(key) {
    return this._style[key]
  },
  /**
   * 开启编辑模式
   */
  drawStart() {
    this.setOptions("isDrawingMode", true)
  },
  /**
   * 关闭编辑模式
   */
  drawEnd() {
    this.setOptions("isDrawingMode", false)
  },
  /**
   *先将画布移动到相同中心点，再根据中心点缩放 
   */

}

/**
* 绘制折线
*/
function drawpolyline() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  if (!that._drawCachePolygonPoint) {
    that._drawCachePolygonPoint = { x, y }
  }
  if (!this._drawPolygonPoints) {
    that._drawPolygonPoints = [];
  }
  _drawOptions._drawingobj = {
    target: null,
    draw: function (start, end) {
      if (that._drawPolygonPoints.length > 1) {
        that._drawPolygonPoints.pop(end.absolutePointer);
      }
      that._drawPolygonPoints.push(end.absolutePointer);
      let polygon = new fabric.Polyline(that._drawPolygonPoints, {
        fill: null,
        angle: 0,
        name: "",
        evented: true,
        opacity: 1,
        visible: true,
        scaleX: 1,
        scaleY: 1,
        stroke: fill,
        strokeWidth: strokeWidth,
        zIndex: 1,
        perPixelTargetFind: true
      }
      );
      //  that._drawCachePolygonPoint
      that.root.remove(that._drawCachePolygon)
      this.target = that._drawCachePolygon = polygon;
      that.root.add(polygon)
      that.root.renderAll()
    },
    drawend: function (start, end) {

      that._drawPolygonPoints.push(end.absolutePointer);
      let polygon = new fabric.Polyline(that._drawPolygonPoints, {
        fill: null,
        angle: 0,
        name: "",
        evented: true,
        opacity: 1,
        visible: true,
        scaleX: 1,
        scaleY: 1,
        stroke: fill,
        strokeWidth: strokeWidth,
        zIndex: 1,
        perPixelTargetFind: true
      }
      );
      //  that._drawCachePolygonPoint
      that.root.remove(that._drawCachePolygon)
      this.target = that._drawCachePolygon = polygon;
      that.root.add(polygon)
      that.root.renderAll()
    },
    dblclick: function (start, end) {
      // that._drawCachePolygon.setCoords();

      that._drawCachePolygon.points.splice(-2,2);
      that.root.fire("add", { target: that._drawCachePolygon });
      that.root.fire("drawend", {
        target: that._drawCachePolygon
      })
      that._drawCachePolygon = null;
      that._drawCachePolygonPoint = null;
      that._drawPolygonPoints = null;
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
}
/**
* 绘制多边形
*/
function drawpolygon() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  if (!that._drawCachePolygonPoint) {
    that._drawCachePolygonPoint = { x, y }
  }
  let _drawCachePolygon = that._drawCachePolygon || {}
  if (!this._drawPolygonPoints) {
    that._drawPolygonPoints = [];
  }
  _drawOptions._drawingobj = {
    target: null,
    draw: function (start, end) {
      if (that._drawPolygonPoints.length > 1) {
        that._drawPolygonPoints.pop(end.absolutePointer);
      }
      that._drawPolygonPoints.push(end.absolutePointer);
      let polygon = new fabric.Polygon(that._drawPolygonPoints, {
        fill: fill,
        angle: 0,
        name: "",
        evented: true,
        opacity: 1,
        visible: true,
        scaleX: 1,
        scaleY: 1,
        stroke: stroke,
        strokeWidth: strokeWidth,
        zIndex: 1,
        perPixelTargetFind: true
      }
      );
      //  that._drawCachePolygonPoint
      that.root.remove(that._drawCachePolygon)
      this.target = that._drawCachePolygon = polygon;
      that.root.add(polygon)
      that.root.renderAll()
    },
    drawend: function (start, end) {
      that._drawPolygonPoints.push(end.absolutePointer);
      let polygon = new fabric.Polygon(that._drawPolygonPoints, {
        fill: fill,
        angle: 0,
        name: "",
        evented: true,
        opacity: 1,
        visible: true,
        scaleX: 1,
        scaleY: 1,
        stroke: stroke,
        strokeWidth: strokeWidth,
        zIndex: 1,
        perPixelTargetFind: true
      }
      );
      //  that._drawCachePolygonPoint
      that.root.remove(that._drawCachePolygon)
      this.target = that._drawCachePolygon = polygon;
      that.root.add(polygon)
      that.root.renderAll()
    },
    dblclick: function (start, end) {
      that._drawCachePolygon.points.splice(-2,2);
      // that._drawCachePolygon.setCoords();
      that.root.fire("add", { target: that._drawCachePolygon });
      that.root.fire("drawend", {
        target: that._drawCachePolygon
      })
      that._drawCachePolygon = null;
      that._drawCachePolygonPoint = null;
      that._drawPolygonPoints = null;
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
}
/**
 * 绘制路径
 */
function drwapath() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  var PencilBrush = new fabric.PencilBrush(this.root);
  PencilBrush.width = strokeWidth;
  PencilBrush.color = stroke
  that.root.isDrawingMode = true;
  PencilBrush.onMouseDown(new fabric.Point(x, y));
  _drawOptions._drawingobj = {
    target: PencilBrush,
    draw: function (start, end) {
      PencilBrush.onMouseMove(end.absolutePointer);
      that.root.setCursor(this.freeDrawingCursor);
    },
    drawend: function (start, end) {
      PencilBrush.onMouseUp();
      that.root.isDrawingMode = false;
      that.root._objects[0].perPixelTargetFind = true
      that.root.fire("add", { target: that.root._objects[0] });
      that.root.fire("drawend", {
        target: that.root._objects[0]
      })
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
}
/**
 * 绘制矩形
 */
function drawrect() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style;
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  var rect = new fabric.Rect({
    left: x,
    top: y,
    fill: fill,
    angle: 0,
    width: 0,
    name: "",
    cacheWidth: 0,
    cacheHeight: 0,
    evented: true,
    opacity: 1,
    visible: true,
    scaleX: 1,
    scaleY: 1,
    height: 0,
    stroke: stroke,
    strokeWidth: strokeWidth,
    zIndex: 1
  });
  that.root.add(rect);
  _drawOptions._drawingobj = {
    target: rect,
    draw: function (start, end) {
      end = end.absolutePointer
      this.target.set("width", parseFloat(end.x - start.x, 10));
      this.target.set("height", parseFloat(end.y - start.y, 10));
      that.root.renderAll();
    },
    drawend: function (start, end) {
      this.target.setCoords();
      that.root.fire("add", { target: this.target });
      that.root.fire("drawend", {
        target: this.target
      });
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }

  };
}
/**
 * 绘制点
 * 绘制点是指定大小的圆作为点
 */
function drawponit() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let point = new fabric.Circle({
    left: x,
    top: y,
    fill: fill,
    radius: 2,
    angle: 0,
    name: "",
    stroke: stroke,
    cacheWidth: 0,
    cacheHeight: 0,
    evented: true,
    opacity: 1,
    visible: true,
    scaleX: 1,
    scaleY: 1,
    strokeWidth: 0,
    hasControls: false,
    // hasBorders:false,
    evented: false
  });
  that.root.add(point);
  _drawOptions._drawingobj = {
    target: point,
    draw: function (start, end) {
      return;
    },
    drawend: function (start, end) {
      this.target.setCoords();
      that.root.fire("add", { target: this.target });
      that.root.fire("drawend", {
        target: this.target
      });
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
  that.root.fire("mouse:up");
}
/**
 * 绘制线
 */
function drawline() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  var line = new fabric.Line([x, y, x, y], {
    fill: stroke,
    stroke: fill,
    strokeWidth: strokeWidth,
    angle: 0,
    name: "",
    evented: true,
    opacity: 1,
    visible: true,
    cacheWidth: 0,
    cacheHeight: 0,
    scaleX: 1,
    scaleY: 1,
    hasControls:false,
    hasBorders:false,
    perPixelTargetFind: true
  });
  that.root.add(line);
  _drawOptions._drawingobj = {
    target: line,
    draw: function (start, end) {
      end = end.absolutePointer
      this.target.set({ x2: end.x, y2: end.y });
      that.root.renderAll();
    },
    drawend: function (start, end) {
      this.target.setCoords();
      that.root.fire("add", { target: this.target });
      that.root.fire("drawend", {
        target: this.target
      });
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
}
/**
 * 绘制圆
 */
function drawcircle() {
  let that = this;
  let _drawOptions = that._drawOptions;
  let _style = that._style
  let x = _drawOptions._start.x;
  let y = _drawOptions._start.y;
  let fill = _style.fill;
  let stroke = _style.stroke;
  let strokeWidth = _style.strokeWidth;
  //创建对象的时候必须包含这些元素，不然在后期修改的时候Vue无法监听到对应属性
  // 如果不使用Vue属性监听则无所谓
  var Circle = new fabric.Circle({
    left: x,
    top: y,
    fill: fill,
    radius: 0,
    angle: 0,
    name: "",
    cacheWidth: 0,
    cacheHeight: 0,
    evented: true,
    opacity: 1,
    visible: true,
    scaleX: 1,
    scaleY: 1,
    borderWidth: 10,
    strokeWidth: strokeWidth,
    stroke: stroke,
    zIndex: 10,
    startAngle: 0,
    endAngle: Math.PI * 2
  });
  that.root.add(Circle);
  _drawOptions._drawingobj = {
    target: Circle,
    draw: function (start, end) {
      end = end.absolutePointer
      function l(s, e) {
        var dx = s.x - e.x,
          dy = s.y - e.y;
        return Math.sqrt(dx * dx + dy * dy);
      }
      let ls = Math.abs(l(start, end));
      this.target.set("radius", ls);
      this.target.set("top", start.y - ls);
      this.target.set("left", start.x - ls);
      that.root.renderAll();
    },
    drawend: function (start, end) {
      this.target.setCoords();
      that.root.fire("add", { target: this.target });
      that.root.fire("drawend", {
        target: this.target
      });
      that.root.selection = true;
      // that._drawOptions.drawtype = null;
      that.root.drawing = false
      that._drawOptions._start = null;
      // that.canvas.renderAll()
      that._drawOptions._drawingobj = null;
    }
  };
}

